package com.gary.security.action;

import java.util.ArrayList;
import java.util.List;


import net.sf.json.JSONException;

import org.apache.struts2.ServletActionContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.security.providers.encoding.PasswordEncoder;

import com.gary.core.action.BaseAction;
import com.gary.core.orm.query.DefaultQueryItem;
import com.gary.core.orm.query.QueryFilter;
import com.gary.core.orm.utils.PageList;
import com.gary.core.util.BeanUtil;
import com.gary.core.util.JsonUtils;
import com.gary.security.facade.SecurityFacade;
import com.gary.security.model.DeptInfo;
import com.gary.security.model.RoleInfo;
import com.gary.security.model.UserInfo;
import com.gary.security.repository.UserRepository;


/**
 * user action.
 *
 */
public class UserAction extends BaseAction<UserInfo> {
    /** * serial. */
    static final long serialVersionUID = 0L;
    
    private transient PasswordEncoder passwordEncoder = null;
    
    private transient UserRepository userResp;
    private SecurityFacade facade;
    
    /** logger. */
    private static Logger logger = LoggerFactory.getLogger(UserAction.class);

    /** * user list. */
    private List<UserInfo> list;

    /** * dept list. */
    private List<DeptInfo> deptList;

    /** * role list. */
    private List<RoleInfo> roleList;

    /** * id. */
    private long id;

    /** * dept id. */
    private long deptId;

    /** * message. */
    private String message;

    // ====================================================
    private int start;
    private int limit;
    private String sort;
    private String dir;
    private String ids;
    private Long userId;
    private Long roleId;
    private boolean auth;

    /** * @return success. */
    public String list() {
        this.list = userResp.getAll();
        this.deptList = facade.getDeptList(null);
        return SUCCESS;
    }

    /** * @return forward. */
    public String edit() {
        this.model = userResp.getById(id,true);
        return "forward";
    }

    /** * @return rolesByUser. */
    public String rolesByUser() {
        this.model = userResp.getById(id,false);
        this.roleList = facade.getRoleList(null);

        for (RoleInfo role : roleList) {
            if (model.getRoles().contains(role)) {
                role.setAuthorized(true);
            }
        }

        return "rolesByUser";
    }

    /** * @return auth end. */
    public String auth() {
        UserInfo user = userResp.getById(id,false);
        RoleInfo role = facade.getRoleById(roleId);

        if (!user.getRoles().contains(role)) {
            user.getRoles().add(role);
            userResp.save(user);
        }

        return "auth-end";
    }

    /** * @return auth end. */
    public String unauth() {
        UserInfo user = userResp.getById(id,false);
        RoleInfo role = facade.getRoleById(roleId);

        if (user.getRoles().contains(role)) {
            user.getRoles().remove(role);
            userResp.save(user);
        }

        return "auth-end";
    }

    /** * @param passwordEncoder password encoder. */
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    /** * @return user list. */
    public List<UserInfo> getList() {
        return list;
    }

    /** * @return dept list. */
    public List<DeptInfo> getDeptList() {
        return deptList;
    }

    /** * @return role list. */
    public List<RoleInfo> getRoleList() {
        return roleList;
    }

    /** * @param id long. */
    public void setId(long id) {
        this.id = id;
    }

    /** * @param deptId long. */
    public void setDeptId(long deptId) {
        this.deptId = deptId;
    }

    /** * @param roleId long. */
    public void setRoleId(long roleId) {
        this.roleId = roleId;
    }

    /** * @return message. */
    public String getMessage() {
        return message;
    }

    // ====================================================
    public void setStart(int start) {
        this.start = start;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public void setSort(String sort) {
        this.sort = sort;
    }

    public void setDir(String dir) {
        this.dir = dir;
    }

    /**
     * 分页浏览记录.
     *
     * @throws Exception 异常
     */
    public void pagedQuery() throws Exception {
        // 分页
        int pageNo = (start / limit) + 1;
        QueryFilter filter =new QueryFilter();

        if (sort != null) {
            filter.addOrderBy(sort, dir);
        }

        PageList page = userResp.getPageList(filter, pageNo, limit);

        JsonUtils.write(page,
            ServletActionContext.getResponse().getWriter(), getExcludes(),
            getDatePattern());
    }

    /**
     * 使用json绑定pojo，再将绑定的pojo返回.
     *
     * @return T entity
     * @throws Exception 解析时，可能抛出异常
     */
    protected UserInfo bindObject() throws Exception {
        UserInfo user = null;

        try {
            user = userResp.getById(model.getId(),true);
        } catch (JSONException ex) {
            System.err.println(ex);
        }

        if (user == null) {
        	QueryFilter filter=new QueryFilter();
        	filter.addQueryItem(new DefaultQueryItem("and","username",model.getUsername()));
        	List<UserInfo> l=userResp.getAll(filter);
            if (l!=null && l.size() > 0) {
                throw new Exception("User already exists.");
            }

            user = model;
            logger.info("{}", user);
            logger.info("{}", passwordEncoder);
            user.setPassword(passwordEncoder.encodePassword(
                    user.getPassword(), null));
        } else {
            BeanUtil.copyProperties(user, model);
        }

        return user;
    }

    /**
     * 保存，新增或修改.
     *
     * @throws Exception 异常
     */
    public void save() throws Exception {
        UserInfo entity = bindObject();
        DeptInfo dept = facade.getDeptById(deptId);
        entity.setDept(dept);
        userResp.save(entity);
        ServletActionContext.getResponse().getWriter()
                            .print("{success:true}");
    }

    /**
     * 读取数据.
     *
     * @throws Exception 异常
     */
    public void loadData() throws Exception {
        UserInfo entity = userResp.getById(id,true);

        if (entity != null) {
            List<UserInfo> list = new ArrayList<UserInfo>();
            list.add(entity);
            JsonUtils.write(list,
                ServletActionContext.getResponse().getWriter(),
                getExcludes(), getDatePattern());
        }
    }

    /**
     * 删除记录.
     *
     * @throws Exception 异常
     */
    public void remove() throws Exception {
        for (String str : ids.split(",")) {
            try {
                long id = Long.parseLong(str);
                userResp.deleteById(id);
            } catch (NumberFormatException ex) {
                continue;
            }
        }

        ServletActionContext.getResponse().getWriter()
                            .print("{success:true}");
    }

    public void setIds(String ids) {
        this.ids = ids;
    }

    /** * @return excludes. */
    public String[] getExcludes() {
        return new String[] {
            "hibernateLazyInitializer", "roles", "menus", "rescs", "users"
        };
    }

    public String getDatePattern() {
        return "yyyy-MM-dd";
    }

    /**
     * 显示用户对应的角色列�?
     *
     * @throws Exception 异常
     */
    public void getRoles() throws Exception {
        UserInfo user = userResp.getById(userId,false);
        List<RoleInfo> roles = facade.getRoleList(null);

        if (user != null) {
            for (RoleInfo role : roles) {
                if (user.getRoles().contains(role)) {
                    role.setAuthorized(true);
                }
            }
        }

        JsonUtils.write(roles,
            ServletActionContext.getResponse().getWriter(), getExcludes(),
            getDatePattern());
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public void setAuth(boolean auth) {
        this.auth = auth;
    }

    /**
     * 授权与撤消授�?
     *
     * @throws Exception 异常
     */
    public void authRole() throws Exception {
        UserInfo user = userResp.getById(userId,false);
        RoleInfo role = facade.getRoleById(roleId);

        if (auth) {
            if (!user.getRoles().contains(role)) {
                user.getRoles().add(role);
            }
        } else {
            if (user.getRoles().contains(role)) {
                user.getRoles().remove(role);
            }
        }

        userResp.save(user);
        ServletActionContext.getResponse().getWriter()
                            .print("{success:true}");
    }
}
